home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection 1998 Fall: Game Toolkit / Disc.iso / Samples / Moofwars 1.02 / MoofWars Sprocket / •Source / TSpriteCollection.cp < prev    next >
Encoding:
Text File  |  1997-11-05  |  5.1 KB  |  181 lines  |  [TEXT/CWIE]

  1. /*************************************************************************************
  2. TSpriteCollection.cp
  3.  
  4. This class represents a group of related Sprites.  For example, all of the shots
  5. fired by a sprite.  In general, the various things that happen to sprites (moving,
  6. drawing, hit testing) all happen to a whole group at a time.
  7.  
  8. Author: Timothy Carroll
  9. Apple Developer Technical Support
  10. timc@apple.com
  11.  
  12. Modification History: 
  13. 1/23/97     TMC        Added include for Moofwars.h so that MrC will compile
  14. 8/15/96        TMC     Initial Release
  15.  
  16. Copyright © 1996, 1997 Apple Computer, Inc., All Rights Reserved
  17.  
  18. You may incorporate this sample code into your applications without
  19. restriction, though the sample code has been provided "AS IS" and the
  20. responsibility for its operation is 100% yours.  However, what you are
  21. not permitted to do is to redistribute the source as "DSC Sample Code"
  22. after having made changes. If you're going to re-distribute the source,
  23. we require that you make it clear in the source that the code was
  24. descended from Apple Sample Code, but that you've made changes.
  25. *************************************************************************************/
  26.  
  27.  
  28. #include "Moofwars.h"
  29. #include "TSpriteCollection.h"
  30.  
  31. TSpriteCollection::TSpriteCollection(void)
  32. {
  33.     fSpriteListHead = NULL;
  34. }
  35.  
  36. TSpriteCollection::~TSpriteCollection(void)
  37. {
  38.     TSprite *currentSprite, *nextSprite;
  39.  
  40.     nextSprite = fSpriteListHead;
  41.     
  42.     while (nextSprite != NULL)
  43.     {
  44.         currentSprite = nextSprite;
  45.         nextSprite = currentSprite->fNextSprite;
  46.         
  47.         // When we delete a group, we make all of the sprites invisible.  This kills a warning
  48.         // in the sprite code.
  49.         currentSprite->SetVisibility(kInvisible);
  50.         delete currentSprite;
  51.     }
  52.     
  53. }
  54.  
  55. void TSpriteCollection::AddSprite (TSprite *theSprite)
  56. {
  57.     if (fSpriteListHead == NULL)
  58.         fSpriteListHead = theSprite;
  59.     else
  60.     {    
  61.         theSprite->fNextSprite = fSpriteListHead;
  62.         fSpriteListHead->fPrevSprite = theSprite;
  63.         theSprite->fPrevSprite = NULL;
  64.         fSpriteListHead = theSprite;
  65.     }
  66. }
  67.  
  68. void TSpriteCollection::RemoveSprite (TSprite *theSprite)
  69. {    
  70.     TSprite *prevSprite, *nextSprite;
  71.     
  72.     prevSprite = theSprite->fPrevSprite;
  73.     nextSprite = theSprite->fNextSprite;
  74.     
  75.     if (prevSprite == NULL)
  76.         fSpriteListHead = nextSprite;
  77.     else
  78.         prevSprite->fNextSprite = nextSprite;
  79.         
  80.     if (nextSprite != NULL)
  81.         nextSprite->fPrevSprite=prevSprite;
  82. }
  83.  
  84. void TSpriteCollection::ProcessSpriteGroup (void)
  85. {
  86.     TSprite *currentSprite, *nextSprite;
  87.  
  88.     nextSprite = fSpriteListHead;
  89.     
  90.     // Just a comment about the structure of these loops.  We get the next
  91.     // sprite before we call process sprite because process sprite can delete
  92.     // the sprite which would throw our iterator off completely.
  93.     
  94.     // We're using the same structure in all of the other loops as well. However,
  95.     // any routine that is disallowed from destroying a sprite (for example, 
  96.     // drawing and erasing should probably never actually destroy a sprite), then
  97.     // we can use a simpler structure:
  98.     
  99.     /*
  100.     currentSprite = fSpriteListHead;
  101.     while (currentSprite != NULL)
  102.     {
  103.         currentSprite->foo();
  104.         currentSprite = currentSprite->fNextSprite;
  105.     }
  106.     */
  107.     while (nextSprite != NULL)
  108.     {
  109.         currentSprite = nextSprite;
  110.         nextSprite = currentSprite->fNextSprite;
  111.         currentSprite->ProcessSprite();
  112.     }
  113. }
  114.  
  115.  
  116. // HitTest routine currently uses some of the inner knowledge of how TSprite works.
  117. // So if TSprite is modified, this routine may need to be altered.  This is an ugly
  118. // routine, and I only do it here to cache some information.  I need to test and see
  119. // if these optimizations are doing anything.
  120.  
  121. void TSpriteCollection::HitTest (TSpriteCollection *targetGroup)
  122. {
  123.     TSprite *currentTarget, *nextTarget, *currentSprite, *nextSprite;
  124.     TGraphic *targetGraphic, *spriteGraphic;
  125.     SInt32 targV, targH, spriteV, spriteH;
  126.     
  127.     nextTarget = targetGroup->fSpriteListHead;
  128.     nextSprite = this->fSpriteListHead;
  129.     
  130.     // quick short circuit
  131.     if (nextTarget == NULL || nextSprite == NULL)
  132.         return;
  133.     
  134.     while (nextTarget != NULL)
  135.     {
  136.         currentTarget = nextTarget;
  137.         nextTarget = currentTarget->fNextSprite;
  138.  
  139.         if (currentTarget->GetVisibility () == kInvisible)
  140.             continue;
  141.             
  142.         targH = (currentTarget->fCoordX >> 16) - currentTarget->fXOffset;
  143.         targV = (currentTarget->fCoordY >> 16) - currentTarget->fYOffset;
  144.         targetGraphic = currentTarget->fSpriteImages->GetTGraphic(currentTarget->fFace);
  145.         
  146.         nextSprite = this->fSpriteListHead;
  147.         while (nextSprite != NULL)
  148.         {
  149.             currentSprite = nextSprite;
  150.             nextSprite = currentSprite->fNextSprite;
  151.  
  152.             if (currentSprite->GetVisibility () == kInvisible)
  153.                 continue;
  154.             
  155.             spriteH = (currentSprite->fCoordX >> 16) - currentSprite->fXOffset;
  156.             spriteV = (currentSprite->fCoordY >> 16) - currentSprite->fYOffset;
  157.             spriteGraphic = currentSprite->fSpriteImages->GetTGraphic(currentSprite->fFace);
  158.             
  159.             if (TGraphic::Intersect (targetGraphic, spriteGraphic, targV,targH,spriteV,spriteH))
  160.             {
  161.                 currentTarget->Collision(currentSprite);
  162.                 currentSprite->Collision(currentTarget);
  163.             }
  164.         }
  165.     }
  166. }    
  167.  
  168. void TSpriteCollection::DrawSpriteGroup (void)
  169. {
  170.     TSprite *currentSprite, *nextSprite;
  171.  
  172.     nextSprite = fSpriteListHead;
  173.     
  174.     while (nextSprite != NULL)
  175.     {
  176.         currentSprite = nextSprite;
  177.         nextSprite = currentSprite->fNextSprite;
  178.         currentSprite->DrawSprite();
  179.     }
  180.  
  181. }